#include "Class.h"
#define _CRT_SECURE_NO_WARNINGS     
#include<stdio.h>
#include<string.h>
6 #include<assert.h>

//自定义函数
//自定义加法函数
//自定义函数extern int printk();//extern声明函数来自外部其他.c文件  
 //但是因为打了int printk();默认前面有extern所以写不写extern都行
 // 
 int z = 100;
 // 
 // 
//自定义函数必须放在main函数前面外面不然会报错   里面和后面都不行
// 自定义函数在设计时要考虑   函数参数 返回值 功能 名字
// 函数内部尽量不要有printf等输出决策性功能printf放main函数里去h函数复用性强1
// 加法函数
int Add(int x, int y)
{
	return x + y;
}

//闰年判断函数
int is_leap_year(int y)//这个y是形参不存实参时不占内存    
//用来存储实参  存实参时形参实参地址不一样  形参是实参的临时拷贝

{
	if (((y % 4 == 0) && (y % 100 != 0)) || (y % 400 ==0))//一个=报错表达式必须是可修改的左值
		return 1;
	else
		return 0;
}

//每月有几天
int get_days_of_month(int y,int m)
{
	int days[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
	int d = days[m];
	if (is_leap_year(y) == 1 && m == 2)//函数调用要在括号里声明变量要有(y)
	d+=1;

	return d;//自定义函数返回值得结果是main函数内部需要的结果
}
//打印
void menu(void)//void表示没有返回值  menu(void)表示没有参数   在main里传参时menu(1) menu('a')会报错
//menu()有参无参都可以在main函数的menu可以传任意参数不报错meun（1)
{
	printf("*************************************\n");
	printf("*****         1play            ******\n");
	printf("*****         2exit            ******\n");
	printf("*************************************\n");
}

//函数中的return语句
//打印1-n的值
void print(int n)
{
	
	if (n < 1)
		return;//如果遇到某个条件时要直接结束函数直接用if()return的写法return不带返回值
	
	for (n= 0;n<= 10; n++)
	printf("%d ",n);
}


//算阶乘的函数
// int FACT(int n)
// {
// 	if (n == 0)
// 		return 1;
// 	else
// 		return (n * FACT(n - 1));
// }
int FACT(int n)
{
	int i = 0;
	int ret = 1;
	for(i=1;i<=n;i++)//i不能等于0
	{
		ret = ret * i;
	}
	return ret;
}

//正序打印一个数
int Print(int n)
{
	if (n > 9)
	{
     Print(n / 10);
	}
		
	printf("%d ", n%10);

}

//求第n个斐波那契数
// int count = 0;
// int Fib(int n)
// {
// 	if (n == 3)
// 		count++;
// 	int ret = 1;
// 	if (n >2)//这里不能取等    不存在Fib0但是else里是1Fib2=1+1=2
// 		return ret = (Fib(n - 1) + Fib(n - 2));
// 	else
// 		return 1;
// }

int Fib(n)
{
	int a = 1;
	int b = 1;
	int c = 1;
	while (n >= 3)
	{
		c = a + b;
		a = b;
		b = c;
		n--;
	}
	return c;
}




 //int printk()   //自定义函数名称不能带数字
//{
//	printf("hrhr\n");
//	printf("hehe");
//}
//函数定义 
//函数定义放在main函数前面时相当于一中特殊声明

//不用在这个.c文件里面声明和定义，也不要再创一个.h文件声明，
// 再创一个.c文件1在这个.c文件1里定义 就能在这个,c文件里用
 //int my_strlen(char* str)
 //{
	// char* start = str;//初始地址arr[0]
	// while (*str != '\0')
	// {
	//	 str++;
	// }//循环结束后str=&arr[7]=&\0
	// return str - start;
 //}

 int my_strlen(char* str)
 {
	 int count = 0;
	 
	 while (*str != '\0')
	 {
		 count++;
		 str++;
	 }//循环结束后str=&arr[7]=&\0
	 return count;
 }


 int *test1()
 {
	 int t= 100;
	 return &t;
 }
 //输出两数最大值的函数
 int max(int x, int y)
 {
	 return (x > y ? x : y);
 }
 
 //交换两个变量的函数
 void swep(int x, int y)
 {
	 int z = 0;
	 z = x;
	 x = y;
	 y = z;

 }
 int swep2(int* pa, int* pb)
 {
	 int tmp = 0;
	 tmp = *pa;//tmp=a
	 *pa = *pb;//a=b
	 *pb = tmp;//b=tmp
 }

 //数组传参打印数组
void print2(int arr[10], int sz)//arr[]不是arr
 {
	 for (int i = 0; i < sz; i++)
	 {
		 printf("%d ",arr[i]);
	 }

 }
int TEST(int arr[])
{
	int sz2 = sizeof(arr)/sizeof(arr[0]);
	printf("%d\n", sz2);
}


//void set_arr(int arr[], int sz)
//{
//	for (int i = 0;i < sz;i++)
//		arr[i] = i + 1;
//}

//void print_arr(int arr[], int sz)
//{
//	for (int i = 0; i < sz;i++)
//		printf("%d\n", arr[i]);
//}

void set_arr(int *arr, int sz)
{
	for (int i = 0; i < sz; i++)
		*(arr+1) = i + 1;
}
void print_arr1(int *arr, int sz)
{
	for (int i = 0; i < sz; i++)
		printf("%d\n", *(arr+1));//不能是*(arr+1)=i+1这样在初始化前打印也是1-10
}

//冒泡排序
//升序
void bublle_sort(int arr[], int sz)//自定义函数末尾没有return就是void
{
	int i = 0;
	for (i = 0; i < sz-1; i++)
	{
		int flag = 1;
		int j = 0;
		for (j = 0; j < sz - 1 - i; j++)
		{
			if (arr[j] > arr[j+ 1])//这里使用的变量是j不是i
			{
				flag = 0;
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;//做交换不用初始化int_
			}
		}
		if (flag == 1)
		{
			break;
		}
	}
}
void print_arr2(int arr[], int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d\n", arr[i]);
	}
}





//二维数组传参
//void test2(int arr[3][5], int r, int c)
//{
//	int i = 0;
//	for (i = 0; i < r; i++)
//	{
//		int j = 0;
//		for (j = 0; j < c; j++)
//		{
//			printf("%d ",arr[i][j]);
//		}
//		printf("\n");
//	}
//}
//指针写法
void test2(int (*p)[5], int r, int c)//必须是写成数组形式int(*p)[5]  int (*p)是变量形式
{
	int i = 0;
	for (i = 0; i < r; i++)
	{
		int j = 0;
		for (j = 0; j < c; j++)
		{
			printf("%d ",*(*(p+i)+j));//*(*(p+i)+j可以写成p[i][j]（arr[i][j]）直接找到元素省去解引用操作
			//p指向第一行（0）（p+i）指向第i行
			// *（p+i)解引用找到数组第i行首元素0地址 第i行元素地址连续，在+j找到第i行第j列地址
		}
		printf("\n");
	}
}


//函数指针变量
void testz()
{
	printf("hrhhrhh\n");
}

void vakeup_fan1()
{
	printf("播放一首轻音乐\n");
}
void vakeup_fan2()
{
	printf("紧急敲门\n");
}
void vakeup_fan3()
{
	printf("打电话\n");
}
void vakeup_sevice(char name[20], int time, void(*pa)())
{
	printf("到%d点了",time);
	pa();
	printf("叫醒%s\n", name);

}

//qsort快速排序函数
int com_int(const void* p1, const void* p2)
{
	if (*(int*)p1 > *(int*)p2)
		return 1;
	else if ((*(int*)p1 = *(int*)p2))
		return 0;
	else 
		return -1;
}

typedef unsigned int unit;
typedef int* ptr_t;
typedef int(*parr_t)[5];
typedef int(*pf_t)(int, int);
typedef void(*pf1_t)(int);

extern void vakeup_fan1();
extern void vakeup_fan2();
extern void vakeup_fan3();
extern void vakeup_service(char name[20], int time, void(*pa)());
struct Stu//创建结构体   这里不需要输入变量类型
{
	char name[20];//名字   这里为什么要输入一个数组而不是变量char name
	int age;//年龄
};//这里为什么要输入分号;

//通过年龄（数字大小）比较
int cmp_stu_by_age(const void* p1, const void* p2)
{
	return ((struct Stu*)p1)->age - ((struct Stu*)p2)->age;
}
//通过名字（字符串）比较
int cmp_stu_by_name(const void* p1, const void* p2)
{
	//return strcmp(((struct Stu*)p1)->name ,((struct Stu*)p2)->name);//升序
	//strcmp通过比较字符串每个位置上字符ASCII值大小来比较字符串大小的库函数包含在<string.h>里
	//strcmp(a,b) a>b返回值是>0的数 a=b返回值是0 a<b返回值是<0的数
	return strcmp(((struct Stu*)p2)->name, ((struct Stu*)p1)->name);//降序
}


int main(void)
{
	//1打印字符
   
	printf("%s\n","hehe");
	printf("%c\n",'q');
	printf("%d\n", 100);
	printf("%f\n", 3.14);
	// s  hehe
	// d 100
	// f 3.14




		//3找零钱
		int price = 0;
		printf("请输入金额(元):");
		scanf("%d", & price);
		int change = 100 - price;
		printf("找你%d元。\n", change);






	int price = 0;
	int bill = 0;
	int change = 0;

	scanf("%d %d ", &price, &bill);
	change = bill - price;
	if (change > 0) {
		printf("找您%d元：", change);
	}printf("您的钱不够");








	//4计算身高的程序
   int foot;
	int inch;
	scanf("%d %d", &foot, &inch);
	printf("身高是%f米。\n",
   ( (foot+inch/12.0)*0.3048));
   //5计算时间差
   int hour1,minute1;
   int hour2,minute2;
   scanf("%d %d",&hour1, &minute1);
   scanf("%d %d",&hour2,&minute2);
   int t1 = hour1 * 60 + minute1;
   int t2 = hour2 * 60 + minute2;
   int t = t2 - t1;
   printf("时间差是%d小时%d分。",t / 60, t % 60);
   //6求平均数
  int a, b;
   scanf("%d %d", &a, &b);
   double c = (a + b) / 2.0;
   printf("%d和%d的平均值=%f\n", a, b, c);
   //7交换两个变量
    int a = 5;
	int b = 6;
	int t;
	t = a;
	a = b;
	b = t;
	printf("a=%d,b=%d\n", a, b);
	//8求字符串长度

   char arr1[] = "abcdef";
   char arr2[] = { 'a','b','c','d','e','f' };
	printf("%s\n", strlen(arr1));
	printf("%s\n", strlen(arr2));
	//9加加减减
	int a;
	a = 10;
	printf("a++=%d\n", a++);
	printf("a=%d\n", a);
	printf("++a=%d\n", ++a);
	printf("a=%d\n", a);
	//10if语句做时间减法
	int hour1,minute1;
	int hour2,minute2;
	scanf("%d %d", &hour1,&minute1);
	scanf("%d %d", &hour2,& minute2);
	int ih = hour2 - hour1;
	int im = minute2 - minute1;
	if (im < 0) {      //如果im<0,要向小时借位
	  im = 60 + im;//im等于IM+60
	   ih--;        //ih的值因为借位减
	}
	printf("时间差是%d小时%d分。\n",ih, im);
	//11关于关系运算的结果  
	printf("%d\n", 5 == 3);
	printf("%d\n", 5>3);
	printf("%d\n", 5<3);
	//12运算符优先级
	printf("%d\n", 7 >= 3 + 4);

	//13找零计算器
	int price = 0;
	int bill = 0;
	scanf("%d\n", &price);
	scanf("%d\n", &bill);
	printf("找零金额%d\n",bill-price);


	int price = 0;
	int bill = 0;
	scanf("%d %d", &bill,&price);
	printf("找零金额%d\n",bill-price);

	int price = 0;
	int bill = 0;
	printf("请输入金额：");
	scanf("%d", &price);
	printf("请输入票面：");
	scanf("%d", &bill);
	printf("找零金额%d\n", bill - price);

int price = 0;
int bill = 0;
printf("请输入金额：");
scanf("%d", &price);
printf("请输入票面：");
scanf("%d", &bill);
if (bill >= price) {
	printf("找零金额%d\n", bill - price);
}
else {
	printf("你的钱不够.\n");
}


	//  14年纪
int minor = 35;
int age = 0;
scanf_s ("%d", age);
if (age < minor) {
	printf("兄弟，你还挺年轻的");
}


const int MINOR = 35;
int age = 0;
printf("请输入您的年龄：");
scanf("%d", age);

if (age < MINOR) {
	printf("年轻是美好的");
}
printf("年龄决定了您的精神世界，请好好珍惜。\n");

//15比大小
int a, b;
printf("请输入两个整数：");
scanf("%d %d", &a, &b);
int max = 0;
if (a > b) {
	max = a;
}
else {
	max = b;
}
printf("大的那个是%d\n", max);

//16计算薪水
//



//17判断成绩
const int PASS = 60;
int score;
printf("请输入成绩：");
scanf("%d", &score);
printf("你输入的成绩是%d\n", score);
if (score < PASS)
	printf("很遗憾，这个成绩没有及格。");
else
printf("祝贺您，这个成绩及格了。");
printf("再见\n");






const int PASS = 60;
int score;
printf("请输入成绩：");
scanf("%d", &score);
printf("你输入的成绩是%d\n", score);
if (score < PASS)
	printf("很遗憾，这个成绩没有及格。");
else {
	printf("祝贺您，这个成绩及格了。");
	printf("再见\n");
}



//18三数中的最大数
int a, b, c;
	scanf("%d %d %d", &a, &b, &c);
	int max = 0;
	if (a > b) {
		if (a > c) {
			max = a;
		}
		else {
			max = c;
		}
	}
	else {
		if (b > c) {
			max = b;

		}
		else {
	max = c;
}
}
printf("The max is%d", max);*/


//19else匹配
const int READY = 24;
int code = 0;
int count = 0;
scanf("%d %d", &code, &count);
if (code = READY)
if (count < 20)
	printf("一切正常\n");
else
printf("继续等待\n");


////19分段函数
int f = 0;
int x;
scanf("%d",&x);
if (x < 0) {
	f = -1;

}
else if (x ==0) {
	f = 0;
}
else {
	f = 2 * x;
}
printf("%d", f);


//20根据不同值输出不同结果
int type;
scanf("%d",&type);
if (type ==1)
printf("你好");
else if (type== 2)
printf("早上好");
else
printf("啊啊啊啊啊");



//switch case 版


//21成绩转换
printf("请输入成绩");
int grade;
scanf("%d",&grade);
grade /= 10;
switch (grade) {

case9:
	printf("A\n");
	break;
case 8:
	printf("B\n");
	break;
default :
		printf("C\n");

}

// //22四位数以内的数位数
int x;
scanf("%d", &x);
int n = 1;
if (x > 999) {
	n = 4;
}




else if (x > 99) {
	n = 3;
}




else if (x > 9) {
	n = 2;
}



printf("%d\n", n);



// //23用while循环来算位数
int x;
int n = 0;
scanf("%d",&x);
n++;
x /= 10;
while (x > 0) {
	n++;
	x /= 10;
}
printf("%d\n",n);

// //24求平均数
// //我写的错误代码
	/*int number;
	int sum = 0;
	int count = 0;
	scanf_s("%d", &number);
	while (number != 1)
	{
		sum += number;
		count++;
		scanf_s("%d", &number);
	}
	printf("平均数为%f", sum / count);*/





	int number;
	int sum = 0;
	int count = 0;
	
	printf("请输入数字(输入1结束): ");//加入输入提示
	scanf_s("%d", &number);
	
	while (number != 1)
	{
		sum += number;
		count++;
		scanf_s("%d", &number);
	}
	
	if (count > 0) {
		printf("平均数为%.2f", (double)sum / count);//用double确定浮点数除法不用1.0*sum[/.[--
	}
	else {
		printf("没有输入有效数字");
	}

// 		//25数的逆序
	//int x;
	//printf("请输入一个整数: ");
	//scanf("%d", &x);
	//
	//int ret = 0;
	//while (x != 0) {
	//	int digit = x % 10;
	//	ret = ret * 10 + digit;
	//	x /= 10;
	//	printf("x=%d,digit=%d,ret=%d\n", x, digit, ret);
	//}
	//
	//printf("逆序结果: %d\n", ret);


	//	
	// x = 6;
		/*printf("请输入一个数:");
		scanf("%d", &x);
		printf("您输入的数是%d", x);*/
	int x, i;
	int isPrime;
	for (x = 2; x < 100; x++)
	{
		isPrime = 1;
		for (i = 2; i < x; i++)
		{
			if (x % i == 0)
			{
				(isPrime == 0);
				break;
			}
		}
		if (isPrime == 1)
		{
			printf("%d", x);
		}
	}



	//1打印字符

	int a = 6 / 4;
	printf("%d", a);

	double a = 6 / 4.0;
	printf("%f", a);
	//1整数除整数得到的是不取余的部分，算数式里只要有一个小数就会强制转换为小数除法，
	//但是在定义变量时要用浮点型，打印时要%f

	float score = 5;
	score = (score / 20) * 100;
	printf("%f", score);//int %d      float double%f强制转换成小数计算


	double a = 6 % 4.0;
	printf("%f", a);//取余运算时两个算子只能全是整数，不能有小数，小数会报错
	负数取余正负号取决于第一个算子，数取决于绝对值的运算

		int a = 10;
	printf("%d\n", a);//10
	int b = ++a;
	printf("%d\n", a);//11先加一
	//11  ++ --有副作用 只要出现++a或者a++,a的值立刻变化    b=a+1对a没有影响
	printf("%d\n", b);//11后使用
	int c = a++;
	printf("%d\n", c);//11先使用
	printf("%d\n", a);//12后加一

	int a = 10;
	a++;
	printf("%d", a);

	//块作用域
	{
		int a = 10;
		printf("%d", a);
	}
	printf("%d", a);
	//在{}大括号内声明的变量是局部变量只在这个大括号内有用出了这个大括号后显示未定义标识符

	//局部优先
	int a = 10;
	{
		int a = 100;
		printf("%d", a);
	}

	//sizeof算变量大小      %zd和%zu是标准的sizeof占位符
	int arr[12] = { 0 };
	printf("%d", sizeof(arr));
	printf("%d", sizeof(char));//1
	printf("%d", sizeof(int));//4
	printf("%d", sizeof(short));//2
	printf("%d", sizeof(long));//4
	printf("%zd", sizeof(float));//4
	printf("%zd", sizeof(double));//8
	printf("%d", sizeof(3.14f));//4
	printf("%zd", sizeof(3.14));//8

	signed和unsigned
		int a = -10;

	unsigned int b = -10;
	printf("%u", b);//因为无符号但是赋值时是负数所以结果是一个随机数
	//无符号用%u打印





//25-10.3(1)if和else语句
//判断一个数是不是奇数
int num = 0;
printf("请输入一个数：");
scanf("%d", &num);
if(num%2==1)
printf("%d是奇数",num);
else
printf("%d是偶数",num);
//在if成立只有一条语句要执行时建议省略if和else的大括号只要执行语句紧跟if和else就行


// //年龄判断
int a = 0;
printf("请输入你的年龄");
scanf("%d", &a);
printf("你输入的年龄是%d\n", a);
if (a >= 18)
{
printf("你已经成年\n");
printf("可以谈恋爱了");
// ////有多个要执行的语句时必须要打大括号，一个大括号占一行这样美观
// ////在有多个大括号忘了大括号打到哪个函数了的情况下可以鼠标单击一下一个大括号看它是内个函数的
}
else 
{
printf("你还未成年\n");
printf("未成年以学业为主先立业再成家");
}

// // 判断正负数
int  a = 0;
printf("请输入一个值：");
scanf("%d", &a);
 printf("你输入的值是%d\n",a);
 if (a == 0)
 {
	 printf("你输入的值是0");
 }
 else if (a < 0)
 {
	 printf("你输入的值是负数");
 }
 else
 {
 printf("你输入的是一个正数");
 }

int num = 0;
printf("请输入一个数字");
scanf("%d", &num);
printf("你输入的整数是%d", num);
if (num > 0)
{
	if (num % 2 == 0)
	{
		printf("你输入的是一个正偶数");

	}
	else
	{
		printf("你输入的是一个正奇数");
	}
}
else
{
	printf("你输入的是一个非正数");
}
//多重嵌套
// 

int age = 0;
printf("请输入你的年龄：");
scanf_s("%d", &age);
printf("你输入的年龄是：%d\n", age);
if (age < 18)
	printf("少年");
else if (age < 44)
	printf("青年");
else if (age < 59)
printf("中老年");
else if (age < 89)
	printf("老年");
else
printf("老寿星");


int num=3;
if (num = 3)//这个表达式是赋值表达式，结果为3，非零，为真
//if(3=num)//判断相等时把数放等号左边，这样少写等号会报错
//if(3==num)
int i = 1;
int j = 2;
int k = 3;
//if(i<j<k)//这个逻辑是关系运算符i<j的话i<j这个整体替换成1，否则替换成零
	//但是无论是1还是0，都小于3所以都能打印
//如果要表达i<j<k,中间用两个&&连接
if(i<j&&j<k)
printf("hiohiiow");

//练习
int age = 0;
scanf("%d",&age);
if (18 <= age <=36)//错误
if(18<=age&&36>=age)
	printf("青年");

int a = 0;
int b = 0;
scanf("%d",&a);
if(a>5)
	b = 3;
else
b = -3;
printf("%d\n",b);

b = (a > 5 ? 3 : -3);//条件操作符：ifa>5,b=3;else b=-3.
printf("%d", b);
int a = 0;
int b = 0;
scanf("%d,%d", &a,&b);
//int m = (a > b ? a : b);//printf("%d", m);
if (a > b)
printf("%d", a);
else
printf("%d", b);


//10.3.2
// 逻辑操作符
// 反逻辑操作符
int flag = 0;
scanf("%d", &flag);
if (!flag)//相当于if(0==flag)
printf("uihiofio");

int a = 0;
printf("%d", !a);

//与运算符&&，双真才真，其余为假
int month = 0;
scanf("%d", &month);
if (3 <= month&&8 >= month)//if条件判断这一行不能写分号:写;表示if语句结束了
printf("春田");
//或逻辑运算操作符||双假为假，其他为真
int month = 0;
scanf("%d", &month);
if (1== month||2== month||12==month)
printf("dong");


//判断闰年
int year = 0;
scanf("%d", &year);
if (year % 4 == 0 && year % 100 != 0|| (year % 400 == 0))//不等号用！=不是！==，一个=
{
	printf("是闰年\n");
}


//操作符短路问题&&并且同真为真并且左假右不算，||或者左真为真右不算
//判断3个变量相等
int a = 2;
int b = 2;
int c = 2;
if (a == b == c)这中写法不对不能判断3个变量相等。2==2，a==b,所以整个表达式变成1
接下来进行1==c的判断，1！=2，所以没有输出结果
if(a==b&&b==c)
printf("ok");




//switch语句
int num = 0;
//scanf("%d", &num);
if (num % 3 == 0)
printf("余数是0");
else if (num % 3 == 1)
printf("余数是1");
else
printf("余数是2");

int num = 0;
scanf("%d", &num);
switch (num % 3)//一般在函数开头1大括号之前的一行不用分号；因为；相当于空语句用了表示这个函数结束
{  //与if语句一样需要有大括号必须

case 0:
	printf("余数是0");
	break;
case 1://case与数值间要有空格结尾要有分号
	printf("余数是1");
	break;
case 2:
	printf("余数是2");
	break;

case 0:
	printf("余数是0");
	case 1://case与数值间要有空格结尾要有分号
	printf("余数是1");
	case 2:
	printf("余数是2");
//case n:这样写报错，case后面必须是整形常量表达式
	//如果每个case语句没有break语句，输入一个数7后直接跳过case 0,跳转到case1，
	// 但是打印结果是case1和case1后的case语句都打印
	//这层代码结果：余数是1余数是2
}

int day = 0;
scanf("%d", &day);
if (1 == day)
printf("星期一");
else
printf("星期二");
int day = 0;
scanf("%d", &day);
switch (day)
{
case 1:
	printf("星期一\n");
	break;
case 2:
	printf("星期二\n");
	break;
case 3:
	printf("星期三\n");
	break;
case 4:
	printf("星期四\n");
	break;
case 5:
	printf("星期五\n");
	break;
case 6:
	printf("星期六\n");
	break;
case 7:
	printf("星期天\n");
	break;
}


int day = 0;
scanf("%d", &day);
switch (day)
{

case 1:
case 2:
case 3:
case 4:
case 5:
	printf("工作日\n");
	break;

case 6:
case 7:
	printf("休息日\n");
	break;
//	//去掉break达到一个范围内输入同一个结果的目的
//	//当所有case都不能匹配时走的路径，defeult语句可以放的位置随意可以放在所有case语句的前面，的后面插在case语句里
default:
	printf("输入错误");
	break;
}


//while语句
if (1)
printf("yes");
//结果是1个yes
while (1)
printf("yes");
//结果是满屏的yes
int num = 1;//循环变量初始化
while (num <= 10)//循环条件判断语句
{
	
	if (num == 5)
		//break;//if() break当某种条件发生时要终止循环时使用
	continue;//这次循环里continue之后的代码全部都不执行了直接跳到下一次循环
//所以i++没办法执行i不能变成6陷入死循环
printf("%d\n", num);// 满足循环条件后每轮循环里要做的事     %d后接空格或者接\n
num++;//循环变量调整部分++是以一为公差的等差数列，sum+=2是以2为公差的等差数列

}

int ch = 0;
while ((ch = getchar())!= EOF)
{
	if (ch > '9' || ch < '0')//打单引号''厘米再放东西表示进行的事ASTII的操作比较
		continue;
	putchar(ch);
}


//数的倒序
int n = 0;
int i = 0;
scanf("%d", &n);
printf("你输入的是：%d\n", n);
while (n != 0)
{
	i = n % 10;
	printf("%d \n ", i);
	n = n / 10;
}

//10.3.3
//for循环
for (int a = 1; a <= 10; a+=2)//for(1变量初始化;int a=1;
//2循环进行条件判断;a<=10;
// 3符合跳到大括号里进行操作;printf
// 4对循环变量进行调整）a+=2
printf("%d ", a);
int a = 1;//初始化
while (a <= 10)//循环条件判断
{
	printf("%d\n", a);//判断后每轮要做的
	a++;//变量调整
}
for (int a = 1; a <= 10; a++)
{
	if (a%3==0)
		continue;
printf("%d ", a);//在for循环里因为a+=2不在大括号里且ctn只能跳大括号里的一轮循环，
////所以无论ctn的位置，ctn都能正常进下一次循环，不会出现死循环的情况
//}


int a = 1;
while (a <= 10)
{
	printf("%d\n", a);
	 a++;//这两步相对于continue的位置很重要在ctn之后就进死循环，在ctn前面能实现只跳这一次循环进下一次循环的目的
	if (a%3==0)
    continue;
	
		//break;//当某个条件发生时要永久的终止并跳出循环
}

//for循环练习
int sum = 0;
for (int a = 1; a <= 100; a++)
{
	if (a % 3 == 0)
		sum += a;
	
}
printf("%d\n", sum);
int sum = 0;
for (int a = 3; a <= 100; a += 3)
{
	if (a % 3 == 0)
		sum += a;
}
printf("sum=%d", sum);





do while
int a = 1;//初始化
do//break和continue都放在do的大括号里
{
	
a++;//调整部分//为了保证不进死循环要放在continue前面//不管while里的循环成不成立都先做do里的代码块
	if (a == 5)
		continue;
printf("%d\n", a);//循环里的功能区//不执行就单独放continue后面
}
while (a <= 10);//判断部分
//在while for do while循环里a++变量调整部分和printf程序块相对if break和if continue的位置影响输出结果

//练习
int c = 0;
for (int a = 1234; ((a % 10) < 10); a / 10)
{
c = (a % 10);
printf("%d", c);
}



//写提前要进行题目分析：1题目目的输出是什么2要有几个变量3用什么函数
int a = 0;
int cnt = 0;
scanf("%d", &a);
printf("你输入的a值是：%d\n", a);
do
{
	cnt++;
	a = a / 10;//1/10=0
	
} while (a );//0为假循环结束
printf("%d", cnt);









打印100-200的素数并统计个数
int i = 0;//初始化
int count = 0;//计数器
for (i = 101;i<=200; i+=2)//完成i从100到200的渐增  //可以优化去掉偶数数据
{
	int flag = 1;//假设i为素数
	for(int j=2;j<=sqrt (i);j++)//完成除数从2到i的渐增      //可以优化把j<i换成j<=sqrt(i)(一定带等号）sqrt(I)包含在头文件#include<math.h>里可以减少计算次数
	{
		if (i % j == 0)
		{
           flag = 0;//赋值的符号和判断的==没有区分开
			break;//通过判断i能不能被2-(i-1)的数整除来判断i是不是素数
		}
	}
	if (flag == 1)
	{
		printf("%d  ", i);//i是素数就打印i
		count++;//每次出现素数加一
	  }
	
			
}
printf("\n%d", count);//打印素数个数


goto语句//直接跳转到字符对应的位置      break一次只能跳出一个循环 goto只要位置合适一次能够跳出多个循环
printf("1\n");
goto a;
printf("2\n");
a:
printf("3\n");


数组
int math[5];
double shu[8];
char zufu[10];
int arr1[5] = { 1,2,3,4,5 };//完全初始化
int arr2[5] = { 1,2,3 };//不完全初始化，空出来的位置默认为0
=必须用{}存放数字用其他括号存放会报错
[]放数字后面{}里的数字个数必须小于[]里的个数
[]里可以不放数字之后系统根据{}里的数字个数自动匹配
int a[5] = { 1,2,3,4,5 };//数组类型为int[5]
n个数的数组下标一共有n-1个第一个对应0，第n个对应n-1,
printf("%d\n",a[4]);//使用数组里的数     数组名称[数对应的下标]
对于一个数组里的一个数进行改动采用直接赋值的方法
a[0] = 9;
printf("%d", a[0]);

打印一个数组所有值   数组和存储下标的i 循环打印arr[i]
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int i = 0;
for (i = 0; i<10; i++)
{
	scanf("\n%d", &arr[i]);
}//for循环通过地址重新输入值

for (i = 0; i<10; i++)//产生所有数组的下标
{
	printf("%d  ",arr[i]);//根据数组下标打印出对应数
}


数组在内存中的位置
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int i = 0;
for (i = 0; i < 10; i++)
{
	printf("arr[%d]的地址是%d\n", &i,&arr[i]);
}
//结果如下以十六进制打印
//arr[11532692]的地址是11532704
//arr[11532692]的地址是11532708
//arr[11532692]的地址是11532712
//arr[11532692]的地址是11532716
//arr[11532692]的地址是11532720
//arr[11532692]的地址是11532724
//arr[11532692]的地址是11532728
//arr[11532692]的地址是11532732
//arr[11532692]的地址是11532736
//arr[11532692]的地址是11532740
//每个地址相差4是一个整型的站位大小
//数组里的数在内存中连续存放
//随着下标增长地址由小到大变化


//sizeof计算数组在内存中占位大小
printf("%d\n",sizeof(int));
int arr[10] = { 1 };
printf("%zd\n", sizeof(arr));//打印数组大小时用%zd
printf("%zd\n", sizeof(int[10]));//直接用数组类型代替数组名称

//计算数组元素个数=数组在内存中总的占位大小/一个数组数的占位大小
//计算数组元素个数并打印数组元素
int arr[10] = { 0 };
int a = sizeof(arr) / sizeof(arr[0]);
//printf("%d", a);
for (int i = 0; i < a; i++)
{
	printf("\n%d",arr[i]);
}


//二维数组的创建和定义
int arr1[2][3] = { 1,2 };//两行三列，只输入两个元素自动占用到第一行前两个位子
int arr2[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
int arr3[4][5] = { {1,2,3,4,5},{1,2,3,4,5},{1,2,3,4,5} };
//通过大括号来整齐指定占用第一个大括号里的指定占用第一行，第二个第二行
int arr4[3][4] = { {1,2}, { 2,1 } };//不完全初始化将1,2放在第一行的第一第二个位子
int arr5[][4] = { 1,2, 2, };//二维数组行可以省略列不能省略   行数按大括号个数算
//不说明且第一行放不满默认只有一行
int arr6[][7] = { {1,2} ,{ 0 },{0} };//根据大括号看有三行

//二维数组的下标
int arr7[4][5] = { {1,2,3,4,5},{1,2,3,4,5},{1,2,3,4,5} };
printf("%d", arr7[0][1]);//二维数组的行列排序和一维数组一样开始都是0一直到n-1

//二维数组的打印
int arr8[3][5] = { 0 };//二维数组定义
int i = 0;
for (i = 0; i < 3; i++)//二维数组输入   先用一个for循环让行数递增 再用一个for循环让列数递增
{
	int j = 0;
	for (j = 0; j < 5; j++)
	{
		scanf("%d", &arr8[i][j]);
	}
}
for (i = 0; i < 3; i++)//二维数组输出
{
	int j = 0;
	for (j = 0; j < 5; j++)
	{
		printf("%d  ", arr8[i][j]);
	}
}

//二维数组在内存中的储存
int arr8[3][5] = { 1,2,3,4,5 ,1,2,3,4,5, 1,2,3,4,5  };
int i = 0;
for (i = 0; i < 3; i++)//二维数组输入   先用一个for循环让行数递增 再用一个for循环让列数递增
{
	int j = 0;
	for (j = 0; j < 5; j++)
	{
		printf("arr8[%d][%d]=%p\n",i,j,arr8[i][j]);
	}
}
//结果如下
arr8[0][0] = 00000001
arr8[0][1] = 00000002
arr8[0][2] = 00000003
arr8[0][3] = 00000004
arr8[0][4] = 00000005
arr8[1][0] = 00000001
arr8[1][1] = 00000002
arr8[1][2] = 00000003
arr8[1][3] = 00000004
arr8[1][4] = 00000005
arr8[2][0] = 00000001
arr8[2][1] = 00000002
arr8[2][2] = 00000003
arr8[2][3] = 00000004
arr8[2][4] = 00000005



//C99变长数组   vs2022不支持，在vscode和gc共同搭建的环境上可以
int n = 0;
scanf("%d", n);
int arr[n];//报错说表达式必须要含有常量
int i = 0;
for (i = 0; i < n; i++)
{
	scanf("%d", arr[i]);
}
for (i = 0; i < n; i++)
{
	printf("%d", arr[i]);
}
//结果应该是输入n等于多少,这个数组中就能存多少数字
//变长数组不能初始化即不能：int arr[n]={1};会报错


//字符char和ASCII编码
//char ch = 'a';
//printf("%c", ch);//打印字符用% c//要打印只能写97或者被赋值为a的字符不能直接写a


//打印所有的可打印字符
for (int ch = 32; ch <= 127; ch++)
{
	printf("%c ", ch);
	if (ch % 10 == 0)
		printf("\n");
}


//10.4.1
//转义字符
//     \?   :printf("??)")在一些旧的编译器会被转换成]    要打印？？）就用printf("\?\?)")
printf("%c\n",'a');//a
printf("%c\n", '\'');//'
printf("%s\n", "a");//a
printf("%s\n","\"");//"
printf("c\test\test.c\n");//c       est     est.c
printf("c\\test\\test.c\n");// c\test\test.c
printf("\a\n");//报警字符：让终端发出报警声并闪烁
printf("helloworld\n");
printf("hello\bworld\n");//hellworld   \b:退格把前面一个字符在终端打印时给删除了
printf("%c\n", '\130');  
//  \130要放在''内
//     \abc表示八进制下的字符如：因为130在ASCII表中八进制表示X所以    \130在打印时结果为X
//但是八进制数字只有1-7，所以abc三个八进制数字不能有8 9
printf("%c\n", '\x38');//8
//十六进制打印与八进制类似
char arr1[5];
char arr[5] = { 'a','b','c','d','e'};
int sz = sizeof(arr) / sizeof(arr[0]);
int i = 0;
for (i = 0; i < sz; i++)
{
	printf("%c  ", arr[i]);//这个地方不能对arr[i]打单引号会报错字符太多
}


//字符初始化时要用char不能用int
char arr1[] = { 'a','b' };//可以用大括号形式初始化数组   
char arr2[] = "ab";//也可以用"字符串的形式初始化数组"   
//但是字符串默认末尾隐藏一个\0 作为结束标志  而且这个\0占用一个字符位看似只有两个占位实际上有三个
//这样去初始化ab是指a和b分别占用一个位点相当于存了两个字符
printf("%s\n", arr1);//ab烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫     
//用大括号打印时最后没有隐藏的默认的\0,所以会自动向后打印直到遇到\0为止
//但是可以认为加一个\0停止打印
printf("%s\n", arr2);//ab
char arr3[] = {'a','b','c','\0'};
printf("%s\n", arr3);//abc

//字符串的输入输出
char arr1[3] = { 0 };
scanf("%s", arr1);
printf("%s",arr1);

//求字符串长度   
char arr1[10] = "abcdef";
printf("%zd\n", strlen(arr1));
strlen  计算含\0的字符串     \0之前的字符个数  头文件<string.h>
strlen返回值类型为size-t类型用%zd打印
char arr2[10] = { 'a','b' };//在打印字符串时默认没有\0会把ab烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫      
但是在打印字符串长度是默认有\0结果只是2
printf("%zd\n", strlen(arr2));
return 0;

char arr3[] = { 'a','b' };
printf("%zd\n", strlen(arr3));//42不完全初始化前后数据未知直到遇到\0停止计算长度

char arr4[] = { 'a','b' ,'\0'};
printf("%zd\n", strlen(arr4));//人工手动创造\0结果显示为2


//gets函数和puts函数
char arr[10];
gets(arr);//读取字符数组的信息 相当于scanf和getchar
printf("%s ", arr);
char arr1[10] = { 'a','b','c' };
char arr2[10] = { 'd','e','f' };
printf("%s", arr1);
printf("%s", arr2);
//结果
//abc
//def
puts(arr1);//隐藏了一个\n换行
puts(arr2);
//结果   abcdef

//函数
// 库函数
double r = 16.0;
printf("%lf\n", sqrt(r));



//函数实现

int a = 0;
int b = 0;
scanf("%d  %d",&a,&b);
int r = Add(a, b);//函数调用
printf("%d", r);



// //闰年判断函数
// int is_leap_year(int y)//这个y是形参不存实参时不占内存    
// //用来存储实参  存实参时形参实参地址不一样  形参是实参的临时拷贝

// {
// 	if (((y % 4 == 0) && (y % 100 != 0)) || (y % 400 ==0))//一个=报错表达式必须是可修改的左值
// 		return 1;
// 	else
// 		return 0;
// }



// //每月有几天
// int get_days_of_month(int y,int m)
// {
// 	int days[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
// 	int d = days[m];
// 	if (is_leap_year(y) == 1 && m == 2)//函数调用要在括号里声明变量要有(y)
// 	d+=1;

// 	return d;//自定义函数返回值得结果是main函数内部需要的结果
// }

// //打印
// void menu(void)//void表示没有返回值  menu(void)表示没有参数   在main里传参时menu(1) menu('a')会报错
// //menu()有参无参都可以在main函数的menu可以传任意参数不报错meun（1)
// {
// 	printf("*************************************\n");
// 	printf("*****         1play            ******\n");
// 	printf("*****         2exit            ******\n");
// 	printf("*************************************\n");
// }


// //函数中的return语句
// //打印1-n的值
// void print(int n)
// {
	
// 	if (n < 1)
// 		return;//如果遇到某个条件时要直接结束函数直接用if()return的写法return不带返回值
	
// 	for (n= 0;n<= 10; n++)
// 	printf("%d ",n);
// }


//函数的声明
//int printk();   //自定义函数名称不能带数字
//可以吧自定义函数主体放在main函数外面前提是要在main函数前对自定义函数做声明:int printk();   带了分号


//算阶乘的函数
// int FACT(int n)
// {
// 	if (n == 0)
// 		return 1;
// 	else
// 		return (n * FACT(n - 1));
// }
// int FACT(int n)
// {
// 	int i = 0;
// 	int ret = 1;
// 	for(i=1;i<=n;i++)//i不能等于0
// 	{
// 		ret = ret * i;
// 	}
// 	return ret;
// }




// //正序打印一个数
// int Print(int n)
// {
// 	if (n > 9)
// 	{
//      Print(n / 10);
// 	}
		
// 	printf("%d ", n%10);

// }

// //求第n个斐波那契数
// int count = 0;
// int Fib(int n)
// {
// 	if (n == 3)
// 		count++;
// 	int ret = 1;
// 	if (n >2)//这里不能取等    不存在Fib0但是else里是1Fib2=1+1=2
// 		return ret = (Fib(n - 1) + Fib(n - 2));
// 	else
// 		return 1;
// }

// int Fib(n)
// {
// 	int a = 1;
// 	int b = 1;
// 	int c = 1;
// 	while (n >= 3)
// 	{
// 		c = a + b;
// 		a = b;
// 		b = c;
// 		n--;
// 	}
// 	return c;
// }



	//int Add(int x, int y)//不带分号分号代表函数语句结束
//{
//	int z = 0;//初始化
//	z = x + y;
//	return z;
//}
//优化加法计算函数
	/*int Add(int x, int y)
	{
		return x + y;
	}*/

	//自定义函数
	//int a = 0;
	//int b = 0;
	//scanf("%d %d", &a, &b);//这里不能输入一个换行号或者空格
	////scanf输入完全按照引号里的要求   输了要再输第三个数才能出前两个数的结果
	////scanf里就两个变量间打空格   不输入换行符没意义  printf可空格可换行
	//int r=Add(a, b);
	//printf("%d\n", r);
	//int year = 0;
	//scanf("%d", &year);//报弹窗就是没打&
	//int ret = is_leap_year(year);//括号里的year是实参
	//if (ret == 1)
	//	printf("yes");
	//else
	//	printf("no

	//函数的链式访问
	//int len = strlen("abcdef");
	//包含在<string.h>里
	//strlen用来求字符串\0之前字符长度  
	// 返回值是size_t其中_是在英文状态下shift-
	//printf("%zd", len);
	//printf("%zd", strlen("abcdef"));
	

	//printf的返回值是打印字符串中字符的个数
	//printf("%d", printf("%d", printf("%d", 43)));//4321
	//由内到外打印最内：43  两个字符所以中层打印结果：2  一个字符外层打印结果：1
	//printf("%d", printf("%d", printf("\n%d", 43)));//4331最层里的\n也被算成一个字符了


	//函数的嵌套调用
	//打印某年某月有多少天
	//int y = 0;
	//int m = 0;
	//scanf("%d %d", &y, &m);
	//int d = get_days_of_month(y,m);
	//printf("%d年%d月有%d天\n",y, m, d);


	//无参数和无返回值
	//menu();

	//自定义函数返回值直接代替main函数中自定义函数出现的位置
	// 函数中的return语句
	//int n = 0;
	//scanf("%d", &n);
	//print(n);

	

	printk();//函数调用
	
	printf("%d", z);

	int i = 0;
	for (i = 0; i < 5; i++)
	{
		test();
	}
	//最简单的递归main();
	

	//用递归算阶乘
	//int n = 0;
	//scanf("%d", &n);
	//int ret = FACT(n);
	//printf("%d\n", ret);
	//正序打印一个数字的每一位数
	//int n = 0;
	//scanf("%d",&n);
	// Print(n);

	//迭代算阶乘
	//int n = 0;
	//scanf("%d", &n);
	//int ret = FACT(n);
	//printf("%d\n", ret);

	//求第n个斐波那契数
    //int n = 0;
	//scanf("%d", &n);
	//int ret = Fib(n);
	//printf("ret=%d\n", ret);
	//printf("count=%d\n", count);
	int num=10;



//int printk()   //自定义函数名称不能带数字
//{
//	printf("hrhr\n");
//	printf("hehe");
//}
//函数定义 
//函数定义放在main函数前面时相当于一中特殊声明

//不用在这个.c文件里面声明和定义，也不要再创一个.h文件声明，
// 再创一个.c文件1在这个.c文件1里定义 就能在这个,c文件里用



















10.6
	int a = 10;//int类型占四个字节每个字节都有自己的地址所以a占四个地址
	//&取地址操作符取的是最小的一个地址
	printf("%p\n", &a);//&取地址操作符  打印地址用%p
	int* pa = &a;
	//pa是指针变量专门用来存放地址的   变量类型int*
	//*说明pa是指针变量   前面的int表示pa指向的a的类型是int 
*pa = 20;//*pa是解引用操作符表示间接访问  *pa=a
	printf("%d", a);
	printf("%d\n", sizeof(pa));//指针变量大小x86  4    x64 8

	char ch = 'w';
	char* pc = &ch;
	printf("%d\n", sizeof(pc));
	printf("%d\n", sizeof(char*));
	printf("%d\n", sizeof(short*));
	printf("%d\n", sizeof(int*));
	printf("%d\n", sizeof(long*));
	printf("%d\n", sizeof(float*));
	printf("%d\n", sizeof(double*));
	//指针变量大小与指向变量大小无关无论是char类型还是int类型     指针变量大小（地址大小）在x86  4    x64 8
    int n = 0x11223344;
	char* pc= &n;
	*pc = 0;
	//int n有四个地址int*定义pa后再用pa去更改n的地址能改四个而char*pc只能改一个
	// 所以对指针变量类型的正确定义有意义
    int n = 0;
	 int* pa = &n;
	 char* pc = &n;
	 printf("%p\n", &n); //00DEFDF8
	 printf("%p\n", &(*pc)); //00DEFDF8
	 printf("%p\n", &(*(pc+1))); //00DEFDF9   加了一个char类型的变量大小1
	 printf("%p\n", &(*pa));//00DEFDF8
	 printf("%p\n", &(*(pa + 1)));//00DEFDFC  加了一个int类型变量大小4
	 //指针类型决定了指针+1-1步长的大小


	 //void*类型
	 int a = 10;//a的值属性10    变量属性int
	 int* pa = &a;//&a的值属性0x12345678 类型int*
	 char* pc = &a;//&a的值属性0x12345678 类型char*
	 //按以上操作对a进行不同变量类型的取地址 可能会报错：初始化从int*到char*不兼容
	 void* pd= &a;//void*泛型指针   无具体类型的指针 好处接收任意类型的地址int*和char*都行
	*pd = 8.8;//坏处void*类型指针不能解引用
	 pd = pd + 1;//坏处void*类型指针不能进行+1-1操作    不知道地址类型不知道+1还是+4
	 // 
	 // 
	 // 
	 // //p是一个指针变量里面存的是地址
	 //*p是通过指针找到的变量（n）
	 //&p是变量p的地址
	 //p没有被const修饰p和*p都可以修改

	 // 
	 //const修饰指针
	int n = 10;
	printf("%d\n", n);
	  n = 20;
	 printf("%d\n", n);
	const int n = 10;//常变量：是个变量但是不能直接去改
	printf("%d\n", n);
	n = 20;//被const修饰变量不能被修改了 会报错
	printf("%d\n", n);
	 int n= 10;
	 int arr1[10] = { 0 };
	 int arr2[n] = { 0 };//报错：数组大小[]里不能放变量
	 const int a = 20;
	 int arr3[a] = { 0 };//报错：常变量：是个变量但是不能直接去改
	 const int k= 10;
	 int* p = &k;
	 *p = 20;
	 printf("%d", k);//指针可以修改const常变量

	int n = 10;
	int m = 20;
	const int* p = &n;//const int*p或者int const*p修饰指针变量放在*的左边
	//限制的是指针指向变量（*p=n)指针指向变量不能再被修改*p=20;报错
	//但是指针变量p本身可以被修改p=m不报错
	int* const p = &n;
	//const放在*右边时修饰限制指针变量p 让p指针变量指向不能再被修改  但是指针指向内容*p可以再被修改
	*p = 20;
	p = m;//指针变量指向从n变为m
	int const* const p = &n;
	*p = 20;
	p = m;
	//在*左右两边加上const后两个都不能改
	




   //指针+-整数
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int* p = &arr[0];//指针变量定义时要取地址加& 这里p+i=&arr[i]
	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	for ( i = 0; i < sz; i++)
	{
		printf("%p == %p\n", &arr[i], p + i);//打印内容要取地址加&  直接p相关的就是地址
	}
	for (i = 0; i < sz; i++)
	{
		printf("%d  ", * p + i);//与*p相关的是指针指向变量内容
	}


	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int* p = &arr[0];//指针变量定义时要取地址加& 这里p+i=&arr[i]
	int i = 9;
	int sz = sizeof(arr) / sizeof(arr[0]);
	for (i = 9; 0<=i&&i <=sz; i--)
	{
		printf("%d  ", *p +i);//与*p相关的是指针指向变量内容
	}

    //指针+-指针
	//在同一个类型和数组里的指针可以加减预算
    int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	printf("%d\n", arr[9] - arr[0]);
	printf("%d\n", arr[0] - arr[9]);//这个是直接元素大小数学相减
	printf("%d\n", &arr[9] - &arr[0]);
	printf("%d\n", &arr[0] - &arr[9]);//这个是地址（指针)数相减   0x11223335-0x11223344=-9
    //不通数组和类型的地址 指针不能加减运算
    int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
	 char arr2[5] = { 1,2,3,4,5 };
	 printf("%d\n", arr2[3] - arr1[4]);//数算数加减
	 printf("%d\n", &arr2[3] - &arr1[4]);//因为存储地址不连续两个无关数组
	// 中间地址不是紧挨着而是随机存储数据的  所以地址不连续

     //通过数组求字符串长度模拟stilen函数作用:统计字符串\0之前字符个数
     char arr1[8] = "abcdef";//这里数组里的数的个数其实是7六个字符一个默认自带的\0
	  int len1 = strlen(arr1);
	  printf("%d\n",len1);//6
	  char arr2[] = "abc\0def";
	  int len2 = strlen(arr2);
	  printf("%d\n", len2);//3
char arr[] = "abcdef";
int len = my_strlen(arr);//数组的数组名为首元素地址即arr==&arr[0]即char*地址
printf("%d\n", len);


int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };//这里数组里的内容都是整形数字所以不能用char要用int
int* p = &arr[0];
int sz = sizeof(arr) / sizeof(arr[0]);
while (p <= &arr[sz-1])
{
	printf("%d\n", *p);
	p++;
}

//野指针
// 1未初始化的指针  变量未初始化他的值是随机变化的
int m;
printf("%d\n", m);
int n = 10;
int* p = &n;
printf("%d\n", *p);
int* m;
printf("%d\n", *m);
int* p;
p = 20;
printf("%d\n", p);


//指针在数组越界
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int* p = &arr[0];
int i = 0;
for (i = 0; i <= 11; i++)//这里i==11超出数组范围所以i=11时地址指针p越界
{
	*(p++) = i;
printf("%d\n",*p);
}



int* p = test1();
printf("%d\n", *p);

//初始化指针
int n = 10;
int* p = &n;//已知指针要初始化为&n
int* p1 = NULL;//未知指针要初始化为什么  初始化为NULL之后的地址无法使用，对这个地址读写都会报错
printf("%d\n", *p1);
scanf("%d\n", NULL);//效果只要初始化为NULL就和别人达成共识这个指针不能用了
//防止指针越界对循环变量范围进行限制改小改大

//指针不用就初始化为NULL，后面要用可以在有p=NULL的情况下在初始化p=10；也可以先用条件判断语句判断是不是NULL

int* p = NULL;
*p = 100;
printf("hehheh");

//不返回自定义函数局部变量的地址




//assert断言    包含在头文件 #include<assert.h>里  
// 如果要关闭assert断言就在预处理模块加#define NDBUG或者换到release版本下关闭断言不进行判断  
// 注释或删除#define NDBUG打开断言
// assert断言失败时会报出失败点在哪个文件哪一行
int num = 0;
scanf("%d",&num);//这里不能有换行符
assert(num == 4);
printf("h");
int a = 10;
int* p = &a;
assert(p != NULL);
printf("jijojoi");

//传值调用和传址调用
int a = 0;
int b = 0;
scanf("%d %d", &a, &b);
int m = max(a, b);//传值调用是把这里输入的a和b传给自定义函数里的x和y
printf("%d", m);

//交换两个变量
// 正常思路
int a = 0;
int b = 0;
scanf("%d %d", &a, &b);
printf("交换前a=%d,b=%d", a, b);
int c = 0;
c = a;
a = b;
b = c;
printf("交换后a=%d,b=%d", a, b);
//传值调用
int a = 0;
int b = 0;
scanf("%d %d", &a, &b);
printf("交换前a=%d,b=%d", a, b);
swep(a, b);
这个swep函数是传值调用
传值调用形参只是实参的一份临时拷贝，形参和实参的储存地址不一样
s所以在自定义函数里对形参的修改对实参没有影响    自定义函数就返回值会影响实参 但是现在所学返回值只有一个
printf("交换后a=%d,b=%d", a, b);
int a = 10;
int* pa = &a;
*pa = 20;//对有a地址的*p进行解引用
printf("%d", a);


//传址调用解决
int a = 0;
int b = 0;
scanf("%d %d", &a, &b);
printf("交换前a=%d,b=%d", a, b);
swep2(&a, &b);
//传址调用：让自定义函数和main函数（swep2的主调函数建立起真正的联系，
// 在自定义函数里通过改变形参来达到改变实参的效果
// 如果只是需要main函数(主调函数）的值带入运算（两个不需要修改的变量）(类似于取最大值）就用传值调用
// int m = max(a, b); void swep(int x, int y)
// 如果要修改main函数里的值就用传址调用  
swep2(&a, &b); int swep2(int* pa, int* pb)
int*pa=&a int *pb=&b
printf("交换后a=%d,b=%d", a, b);


////数组名的理解   数组首个元素地址 = 数组名
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
printf("数组首个元素地址=%p=\n=数组名地址=%p\n", &arr[0], arr);
////第一个数组首元素地址要加& 第二个数组名不用加&打印结果直接是地址
////数组首个元素地址 = 004FFABC == 数组名地址 = 004FFABC


//特例1sizeof(数组名)里数组名表示整个数组   sizeof(数组名)用于求整个数组的大小
int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
printf("%d\n", sizeof(arr));
int sz = sizeof(arr) / sizeof(arr[0]);//sz=40/4=10
//特例2    &arr表示取整个数组的地址！=数组首元素地址
printf("&arr[0]=%p\n", &arr[0]);//首元素地址
printf("&arr[0]+1=%p\n", &arr[0]+1);
printf("arr    =%p\n", arr);//数组名地址
printf("arr+1    =%p\n", arr+1);
printf("&arr   =%p\n", &arr);//数组地址
printf("&arr+1   =%p\n", &arr+1);
//&arr[0] = 012FFD98       8
//& arr[0] + 1 = 012FFD9C  12  加了一个数组元素内存大小4
//arr = 012FFD98           8
//arr + 1 = 012FFD9C       12  加了一个数组元素内存大小4
//& arr = 012FFD98         8
//& arr + 1 = 012FFDC0     48  加了一整个数组内存大小4*10
//&arr取出的是整个数组的地址  +1跳过整个数组内存 而非一个数组内变量内存
//原因指针类型的差异 &arr的类型是数组指针类型 int（*p)[10]


//使用指针访问数组
int arr[10]={ 0 };
int i = 0;
int sz = sizeof(arr)/sizeof(arr[0]);
for (i = 0; i<sz;i++)
{
	scanf("%d",&arr[i]);
	//scanf里只能有%d等表示打印内容的占位符或者是一个scanf里要输入两个变量
	//其他情况下不能有空格和换行符 不然系统不报错但是输入完了按回车不出结果
}
for (i = 0; i < sz; i++)
{
	printf("%d ", arr[i]);
}

int arr[10] = { 0 };
int i = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
int* p = arr;//把首元素地址付给i
for (i = 0; i < sz; i++)
{
	scanf("%d", p+i);//指针p+i表示指针  p=m表示转换指针对象    p+i=arr+i=&arr[i]  首元素地址加i表示第i个元素地址
	//scanf里只能有%d等表示打印内容的占位符或者是一个scanf里要输入两个变量
	//其他情况下不能有空格和换行符 不然系统不报错但是输入完了按回车不出结果
}
for (i = 0; i < sz; i++)
{
	printf("%d ", *(p+i));//解引用*(p+i)表示变量   *（p+i）=*（arr+i）=&（arr[i] ）
}//arr[i]=*(arr+i)






//10.7
//数组传参
//int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
//int sz = sizeof(arr) / sizeof(arr[0]);
//print2(arr, sz);

//自定义函数内arr[]是几
//int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
//int sz1 = sizeof(arr) / sizeof(arr[0]);
//printf("%d\n", sz1);
//
////int TEST(int arr[])//int*arr是指针x64 为8 x86为4
//{
//	int sz2 = sizeof(arr) / sizeof(arr[0]);
//	printf("%d\n", sz2);
//}//在x64是2在x86是1
//TEST(arr);//arr数组名是数组首元素地址


//int arr[10] = {0};
//int sz = sizeof(arr) / sizeof(arr[0]);
//print_arr(arr, sz);
//set_arr(arr, sz);
//print_arr(arr, sz);


//冒泡排序
//升序
//int arr[10] = { 9,8,7,6,5,4,3,2,1,0 };
//int arr[10] = { 2,1,4,3,6,5,8,7,10,9 };
//int sz = sizeof(arr)/ sizeof(arr[0]);
//print_arr2(arr, sz);
//bublle_sort(arr, sz);
//print_arr2(arr, sz);


//int a = 10;
//int * pa=&a;//pa为一级指针变量   *说明pa是指针
//int** ppa = &pa;//ppa是二级指针变量
//printf("%d\n", *pa);
//printf("%d\n", **ppa);
//int b = 100;
//*ppa = b;//pa=b=100通过对二级指针解引用转换一级指针pa的指向
// printf("%d\n",*ppa);//100
// //指针数组还是数组
// int* arr1 = { 0 };
// double* arr2 = { 0 };
//指针数组模拟二维数组
//int arr1[3][5] = { {1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7} };
//int i = 0;
//for (i = 0; i < 3; i++)
//{
//	int j = 0;
//	for (j = 0; j < 5; j++)
//	{
//		printf("%d ", arr1[i][j]);
//	}
//	printf("\n");
//}
//int arr1[5] = { 1,2,3,4,5 };
//int arr2[5] = { 2,3,4,5,6 };
//int arr3[5] = { 3,4,5,6,7 };
//int* parr[3] = { arr1,arr2,arr3 };
//int i = 0;
//for (i = 0; i < 3; i++)
//{
//	int j = 0;
//	for (j = 0; j < 5; j++)
//	{
//		printf("%d ", parr[i][j]);
//	}
//	printf("\n");
//}
//int arr[10] = { 0 };
//int a = 1, b = 2, c = 3;
//int* pa[10] = { &a,&b,&c };//指针数组（int*）（pa[10])
////[]结合优先级大于*     所以是数组 所以先是pa[10]  再是外部int*表示每个元素类型为指向整形的指针   
//int(*pa)[10]=&arr;//数组指针   （)优先级最高所以是指针
////(*p2)表示p2是一个指针  int[10]表示指向一个长度为10的整型数组
//int arr [10] = 10;
////arr=&arr[0]        类型为int *加一跳过4个字节
//int(*p)[10] = &arr;//类型为int *[10] 加一跳过40个字节
//
//
//char*ch[5]={0};
//char* (*pa)[5] = &ch;



//二维数组传参   传的是首元素地址 第一行地址
//int arr[3][5] = { {1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7} };
//test2(arr, 3, 5);

//printf("%p\n",&testz);
//printf("%p\n",testz);
//不同于数组&arr和arr显示一样但是因为类型不一样所以+1跳过大小不一样
//函数的&test和test完全相等

//函数指针变量
//int* p;
//void testz()
//{
//	printf("hrhhrhh\n");
//}

//int (*pa1)() = &testz;


//int Add(int x, int y)
//{
//	return x + y;
//}

//int (*p1)(int, int) = Add;
//int (*p2)(int x, int y) = Add;
//int (*p3)(int, int) = &Add;
//int (*p4)(int x, int y) = &Add;
// |    |         |
// |    |         说明函数变量类型和数量
// |   指针名称
//指针p指向函数的返回类型
//p1函数指针变量类型去掉int (*p1)(int, int)里的p1:int (*)(int, int)  int a;int   int*p;int*
//int (*p2)(int x, int y) = &Add;
//int r = (*p2)(3, 5);//Add(3,5)
//printf("%d", r);
//int m = p2(3, 5);//&Add(3,5)       对于函数Add=&Add
//printf("%d", m);
//int s = Add(3, 4);
//printf("%d\n", s);


//int m = (int)3.14;//强制类型转换把浮点型强制转换成整型
//void(*)()//是一种函数指针类型
//( void(*)())0    //强制把0转换成了一个函数指针（函数的地址）

//(*(void (*) ())0)();
//将0这个数值转化为一个函数地址放一个函数 但是这个函数没有参数返回类型是void
//对这个地址解引用调用函数

//正常函数声明
//int Add(int x, int y);
//int Add(int, int);
//void(*signal(int, void(*)(int)))(int);
//1对于signal(int, void(*)(int))是一个函数声明
// 一个变量类型是int,一个变量类型是函数指针类型 void(*)(int)  函数参数类型int  函数返回值类型为void
//2signal(int, void(*)(int))是一个函数指针变量相当于pa
//化简void(*pa)(int)=void(*)(int )也是一个函数指针类型


//typedef
//unsigned int num = 100;
////在main外部   typedef unsigned int unit
//unit n= 200;//对变量重命名
//printf("%d", n);
//// 在main外部   typedef int*  ptr_r
//ptr_t pa;//对指针类型进行重命名
//int* p1, p2;
////p1是指针变量，p2是整型变量
//int* p1, *p2;
////定义p1和p2都是指针变量
//ptr_t p3, p4;
////定义p3和p4都是指针变量
//对数组指针重命名
//int arr[5] = { 0 };
//int(*p)[5] = &arr;
////typedef int(*parr_t)[5];   不能写成int(*)[5]  parr_t  要把parr_t放在*后面
//parr_t p5, p6;
////对函数指针类型进行重命名
//int (*pa)(int,int) = Add;
//pf_t p7, p8;
////pedef void(*pf1t)(int);
//void(*signal(int, void(*)(int)))(int);
//pf1_t signal(int, pf1_t);//简化版本


//回调函数是什么


//vakeup_service("zhangsan", 10, vakeup_fan1);
//vakeup_service("lisi",24, vakeup_fan2);
//vakeup_service("wangwu",18, vakeup_fan3);//无法解析可能是因为英文单词拼写错误

//qsort快速排序函数
//int arr[] = {1,3,5,7,9,2,4,6,8,0};
//int sz= sizeof(arr) / sizeof(arr[0]);
//qsort(arr, sz, sizeof(arr[0]), cmp_int);
//     //比较数据开始地址，比较数据个数，每个变量大小字节，返回值为int的用于比较两个数据大小的函数int cmp_int(const void* p1, const void* p2)
//int i = 0;
//for (i = 0; i < sz; i++)
//{
//	printf("%d ", arr[i]);
//}
//	struct Stu arr[3] = {{"zhangsan",20},{ "lisi",35 },{ "wangwu",15 }};
//int sz = sizeof(arr) / sizeof(arr[0]);
////qsort(arr, sz, sizeof(arr[0]), cmp_stu_by_age);
//qsort(arr, sz, sizeof(arr[0]), cmp_stu_by_name);
////比较数据开始地址，比较数据个数，每个变量大小字节，返回值为int的用于比较两个数据大小的函数int cmp_int(const void* p1, const void* p2)
//int i = 0;
//for (i = 0; i < sz; i++)
//{
//	printf("%s : %d\n", arr[i].name, arr[i].age);
//}
int ret1 = islower('x');//islower库函数包含在<ctype.h>这个头文件里 
//用于判断一个字符是不是小写字母是返回非零数不是返回0  isupper判断大写字母
//printf("%d\n", ret1);
//int ret2 = isupper('X');//大写字母
//printf("%d\n", ret2);
//int ret3= isdigit('1');//数字
//printf("%d\n", ret3);
////if (ret3)//表示如果ret非零
//if(isdigit('1'))
//{
//	printf("是数字字符");
//}
//char ch = 0;
//scanf("%c" ,& ch);
//if (isdigit(ch))//判断具体数字字符时打引号   判断变量时不打
//{
//	printf("是数字");
//}
//else if (islower(ch))
//{
//	printf("是小写字符");
//}
// 通过遍历数组来打印数组里的字符
//char arr[] = "Test string.\n";
//
//int i = 0;
//while (arr[i])
//{
//	printf("%c", arr[i]);
//	i++;
//}
//把所有小写字母转成大写的  不改变数组内容
//char arr[] = "Test string.\n";
//int i = 0;
//while (arr[i])
//{
//	int ch = arr[i];
//	if (islower (ch))
//	{
//		ch = ch - 32;
//		
//	}
//	printf("%c", ch);
//	i++;
//}
//改变数组内容
//char arr[] = "Test string.\n";
//
//int i = 0;
//while (arr[i])
//{
//	
//	if (islower(arr[i]))
//	{
//		arr[i] = arr[i] - 32;
//
//	}
//	printf("%c", arr[i]);
//	i++;
//}

//字符转换函数  也在<ctype.h>里
//int ch1 = 'a';
//printf("%c", toupper(ch1));
//int ch2 = 'A';
//printf("%c", tolower(ch2));
// 
// 
//char arr[] = "Test string.\n";
//
//int i = 0;
//while (arr[i])
//{
//	
//	if (islower(arr[i]))
//	{
//		arr[i] = toupper(arr[i]);
//
//	}
//	printf("%c", arr[i]);
//	i++;
//}



////strlen  统计字符串\0前字符个数  <string.h>
//size_t len = strlen("abcdef");
//printf("%d\n", len);//返回类型为size_t用%zd打印  其实%d也不报错
//
//
//
//char arr[] = { 'a','b','c','d' };
//size_t len2 = strlen(arr);
//printf("%d\n", len2);
//
//
//char arr1[] = { 'a','b','c','d' ,'\0'};
//size_t len3 = strlen(arr1);
//printf("%zd\n", len3);

//strlen的返回值
const char* arr1[] = { 'a'};
const char* arr2[] = {'a','b'};
 //if (strlen(arr1) - strlen(arr2) > 0)
 //strlen返回值是size_t无符号整型不带正负号
 // 所以  strlen(arr1) - strlen(arr2)=|strlen(arr1) - strlen(arr2)|=|1-2|=1>0
if ((int)strlen(arr1) - (int)strlen(arr2) > 0)//强制转换成有符号整型
 {
	 printf("arr1>arr2");
 }
 else
	 printf("arr1<arr2");
 //结果arr1<arr2

















	return 0;

}
















/10.9
//结构体
//struct student stu1 = { "张三","19","男", "2025" };//分号间隔
//struct student stu2 = { .age = "19",.name = "李四", .id = "2024",.sex = "男" };
//
//
//struct B ABC = { "ab",{"xk","2"},"mckp" };
////结构体成员的直接访问
//struct point p = { 1,2 };
//
//printf("x=%d,y=%d",p.x, p.y);   //p.x,p.y
//scanf("%d %d", &(p.x), &(p.y));
//printf("x=%d,y=%d", p.x, p.y);
//
//    return 0;
//}



//结构体的间接访问

//struct point
//{
//	int x;
//
//	int y;
//};
//
////void setpoint (struct point *prt)
////{
////	//scanf("%d %d", &((*prt).x), &((*prt).y));
////	scanf("%d %d", &(prt->x), &(prt->y));
////}
//
//
//void POINT(struct point* p)
//{
//	printf("%d %d", p->x, p->y);
//}
//int main()
//{
//	struct point p = { 1,0 };
//	//setpoint(&p);
//	//printf("x=%d y=%d", p.x, p.y);
//	POINT(&p);
//
//	return 0;
//}


//struct stu
//{
//	char name[20];
//	int age[23];
//};
//void setstu(struct stu *ps)
//{
//	//ps->name = "张三";//这里指向的是数组名首地址不能更改
//	//	ps->age = "18";
//		strcpy(ps->name, "张三");
//		strcpy(ps->age, "15");
//		
//}
//void printstu(struct stu ss)
//{
//	printf("%s %d", ss.name,ss.age);
//}
//int main()
//{
//	struct stu s = { 0 };
//	setstu(&s);
//	printstu(s);
//}



//结构体内存对齐
//struct stu1
//{
//	char c1;
//	char c2;
//	int c3;
//	
//};
//int main()
//{
//	printf("%d", sizeof(struct stu1));//8
//}

//联合体
//union un
//{
//	char c1;
//	int c2;
//};
//union un2
//{
//	short c3[7];
//	int c4;
//};
//int main()
//{
////printf("%zd\n", sizeof(union un));//4
//	/*union un u = { 0 };
//	printf("%d\n", &u);
//	printf("%d\n", &(u.c1));
//	printf("%d\n", &(u.c2));*/
//	printf("%zd\n", sizeof(union un2));
//}


//int main()
//{
//	int* p = (int*)malloc(20);
//	if (p == NULL)
//	{
//		return 1;
//	}
//	int i = 0;
//	for (i = 0; i < 5; i++)
//	{
//		*(p + i) = i + 1;
//		printf("%d ", *(p + i));
//	}
//	
//}

////判断指针是不是空指针
//
//int main()
//{
//int* p2 = (int*)malloc(5, sizeof(int));
//if (p2 == NULL)
//{
//	perror("malloc");//直接是函数名不打括号
//	return 1;
//}
////使用
//int i = 0;
//for (i = 0; i < 5; i++)
//{
//	*(p2 + i) = i + 1;
//	printf("%d " ,* (p2 + i));
//}
////调整空间大小
//int* prt = (int*)realloc(p2,10*sizeof(int));
////空间调整成功
//if (prt != NULL)
//{
//	p2 = prt;
//}
////空间调整失败
//else
//{
//	perror("ralloc");
//}
////调整成功使用
//for (i = 0; i < 10; i++)
//	{
//		*(p2 + i) = i + 1;
//		printf("%d ", *(p2 + i));
//		}
//
////释放
//free(p2);
//return 0;
//}


//链表节点构建
typedef struct Node
{
	int data;
	struct Node* next;
}Node;
Node* createNode(int b)
{
	Node *p = (Node*)malloc(10, sizeof(int));
	if (p == NULL)
	{
		printf("开辟空间失败");
		return NULL;
	}
	p->data= b;
	p->next = NULL;

	return p;
}
void printlist(Node* p)
{
	Node* cur = p;
	while (cur != NULL)
	{
		printf("%d-->", cur->data);
		cur = cur->next;
	}
	printf("NULL");
}
//int main()
//{
//	Node *p1=createNode(1);
//	Node* p2 = createNode(2);
//	Node* p3 = createNode(3);
//	Node* p4= createNode(4);
//	p1->next = p2;
//	p2->next = p3;
//	p3->next = p4;
//	printlist(p1);
//
//	return 0;
//}
void pushFront(int a, Node**p)
{
	Node* newnode = createNode(a);
	p = newnode;
}
int main()
{
	Node* phead = NULL;
	pushFront(1, &phead);
	pushFront(2, &phead);
	pushFront(3, &phead);
	pushFront(4, &phead);
}
